package test.lambda;

import lombok.Builder;
import lombok.Data;
import lombok.ToString;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Supplier;

import static java.util.stream.Collectors.groupingBy;

/**
 * @author yachao.Guo
 * @version 1.0.0  2019-04-17
 */
@Data
@Builder
@ToString
public class Apple {

    private String color;

    private Double weight;


    public static boolean isGreenApple(Apple apple) {
        String color = "green";
        if (color.equals(apple.getColor())) {
            return true;
        }
        return false;
    }

    public static boolean isHaveWeight(Apple apple) {
        double weight = 50;
        if (apple.getWeight().doubleValue() > weight) {
            return true;
        }
        return false;
    }

    public interface Predicate<T> {

        boolean compare(T t);
    }

    public static List<Apple> filterApples(List<Apple> apples, Predicate<Apple> p) {
        List<Apple> result = new ArrayList<>();
        apples.forEach(apple -> {
            if (p.compare(apple)) {
                result.add(apple);
            }
        });
        return result;
    }


    public static void main(String[] args) {
        List<Apple> apples = new ArrayList<>();
        apples.add(Apple.builder().color("red").weight(Double.valueOf(60)).build());
        apples.add(Apple.builder().color("green").weight(Double.valueOf(40)).build());
        apples.add(Apple.builder().color("green").weight(Double.valueOf(60)).build());

//        List<Apple> result1 = filterApples(apples,Apple::isGreenApple);
//        List<Apple> result2 = filterApples(apples,Apple::isHaveWeight);
//        List<Apple> result3 = filterApples(apples,(Apple a)->a.getWeight().doubleValue()>50 && a.color.equals("green"));
//        result1.test.stream().forEach(apple -> System.out.println(apple.toString()));
//        System.out.println("=============================================");
//        result2.test.stream().forEach(apple -> System.out.println(apple.toString()));
//        System.out.println("=============================================");
//        result3.test.stream().forEach(apple -> System.out.println(apple.toString()));
//        System.out.println("=============================================");
        //顺序执行
//        List<Apple> result4 = apples.test.stream().filter(Apple::isGreenApple).collect(Collectors.toList());
//        result4.test.stream().forEach(apple -> System.out.println(apple.toString()));
//        System.out.println("=============================================");
//        //并行执行
//        List<Apple> result5 = apples.parallelStream().filter(Apple::isGreenApple).collect(Collectors.toList());
//        result5.parallelStream().forEach(apple -> System.out.println(apple.toString()));
//        System.out.println("=============================================");
//        List<Integer> result6 = map(apples,apple ->apple.hashCode());
//        result6.parallelStream().forEach(apple -> System.out.println(apple.toString()));
//        System.out.println("===========test==supplier================================");
//
//        System.out.println(get(()->apples.get(0)));
//        System.out.println("===========test==portNumber================================");
//        int portNumber = 13;
//        Runnable r = () -> System.out.println(portNumber);
//        //portNumber = 19;
//        r.run();
//        Apple a = Apple.builder().color("redd").weight(Double.valueOf(60)).build();
//        Runnable r1 = () -> System.out.println(a);
//        a.setColor("gre");
//        r1.run();
//        apples.sort(Comparator.comparing(Apple::getColor));

      Map<String,List<Apple>> colormap =  apples.stream().collect(groupingBy(Apple::getColor));
        System.out.println(colormap);
    }


    public static <T, R> List<R> map(List<T> list, Function<T, R> f) {
        List<R> result = new ArrayList<>(list.size());
        list.forEach(a -> result.add(f.apply(a)));
        return result;
    }

    public static <T> T get(Supplier<T> s){
        return s.get();
    }


}
